AI 지원 프로그래밍을 위한 새 실천법
AI 지원 프로그래밍 환경에 맞는 새 프로그래밍 실천법에 대한 정리되지 않은 고민들.
주석과 이름의 역할 변화
깃헙 코파일럿이나 Cursor 등이 나오기 전까지는 주석은 사람에게 의미가 있었을 뿐 컴퓨터에게는 아무 의미가 없었다. 이름(변수 이름, 함수 이름, 클래스 이름 등)도 마찬가지. 예를 들어 아래 두 코드는 컴퓨터가 보기에 동일하다(-equivalence).
const blah = a => Math.PI * a * a
const area = r => Math.PI * r * r
하지만 LLM 기반 코딩 지원 도구가 나온 이후로는, IDE가 주석과 이름을 알아먹기 시작했다. 이에 따라 AI 지원 프로그래밍 환경에서는 프로그래머가
const blah = a =>
를 입력하면 편집기가 유익한 제안을 못해주지만const area = r =>
를 입력하면 높은 확률로Math.PI * r * r
를 제안해준다.
주석도 마찬가지다. 주석을 잘 적으면 맥락에 맞는 코드를 더 잘 제안해준다.
좋은 이름을 지어주고 필요한 주석을 적소에 잘 적어주는 건 원래 해야할 일이기 때문에 결과만 보면 별 차이가 없다. 하지만 결과를 만드는 과정에는 제법 큰 차이가 생긴 것 같다. 예:
- TDD를 할 때, 실패하는 테스트를 새로 추가한 뒤에는 최대한 빠르게(대체로 30초 이내에) 녹색 막대를 보는 게 중요하다(참고: TDD 주기). 그래서 이 단계에서는 변수 이름을
blah
,foo
,a
,b
등으로 대충 지은 다음에 테스트가 통과하면 점진적으로 리팩토링을 하곤 한다. 하지만 이름을 대충 지으면 AI의 코드 지원을 제대로 받을 수 없다. - TDD를 할 때에는 테스트를 통과할 수 있는 최소한의 구현을 일단 해놓고서(Fake it) 점진적으로 구현을 유도해가게 되는데, AI는 종종 한 방에 제대로 된 구현을 제안한다. 그러고 나면 다음 테스트를 추가해도 테스트가 깨지지 않기 때문에(왜냐하면 이미 제대로 된 구현이 생겼으니까) 피드백 고리가 끊어진다. 결과적으로 테스트 커버리지가 낮아질 소지가 있다.
한편, 기존 실천과 상충하지 않는 변화도 있다. 몇몇 변화는 기존의 좋은 실천법들이 좀 더 유용하게 만든다. 예:
- 코딩을 하기에 앞서 이번 코딩 세션에서 하려고 계획한 일을 주석에 의사코드 또는 TODO 목록 형태로 적는 일이 잦아졌다. 이는 짝 프로그래밍 세션을 시작할 때 짝이랑 화이트보드나 종이에 낙서를 해가며 짧은 디자인 세션을 여는 것과 유사하며, 장려할만한 실천법이다. 이걸 혼자 코딩하는 상황에서도 더 의식적으로 하게 되었으니 이는 좋은 일이다.
- AI가 주석을 알아듣는 덕에 점진적 개선(stepwise refinement) 기법이 훨씬 유익해졌고, 이에 따라 더 자주 활용하고 있다.
어떤 변화는 좋은지 나쁜지 아직 잘 모르겠다. 예:
- 함수 내부의 주석은 대체로 악취이지만 함수나 모듈 선언부(특히 “published” 인터페이스인 경우)의 주석은 꼼꼼하게 잘 적어주는 게 좋다. 그런데 리팩토링을 충분히 빈번하게 하려면 선언부 주석은 커밋 직전에 적는 게 효율적이다. 그런데 이제는 주석 작성을 AI가 잘 도와주고 리팩토링한 코드에 맞춰 주석을 고치는 일도 AI가 잘 도와주다보니, 주석을 미리 쓰는 게 큰 낭비가 아니게 됐다.
소프트웨어 설계
마틴 파울러의 리팩토링에는 이런 문구가 나온다:
After all, the compiler doesn’t care whether the code is ugly or clean. But when I change the system, there is a human involved, and humans do care. —p4
코드의 구조가 깔끔하건 아니건 컴퓨터(컴파일러)는 신경쓰지 않지만 인간에겐 중요하다는 말이다. 하지만 이제 컴퓨터에게도 깔끔한 코드가 중요해졌다. 의도를 잘 드러내는 코드일수록 AI가 더 잘 작동할 가능성이 커졌기 때문이다.
이런 변화로 인해, 설계를 언제 하는 게 좋을지에 대해서도 더 고민이 필요해졌다.
코드 쓰기와 읽기의 비중 변화
내가 코드를 작성하는 비중이 점점 줄고, AI가 제안한 코드를 검토하는 비중은 점점 늘고 있다. AI가 작성하는 코드가 적어도 절반 이상인 것 같다. 코드를 잘 쓰는 능력보다 코드를 잘 읽는 능력이 훨씬 더 중요해질 것 같다. 코드 읽기에 대한 훈련이 필요하겠다.
AI가 제안하는 코드에는 (아직까지는) 언제나 오류 가능성이 있는데, 인간 프로그래머가 범하는 오류와 조금 다른 종류의 오류를 범하곤 하는 게 문제인 것 같다. 단위 테스트, 강력한 타입 시스템, 프로그램 증명 등의 장점을 잘 취사선택하는 어떤 실천법이 필요하다고 생각한다.
코드 작성 순서의 변화
코드의 어떤 부분을 먼저 작성하면 내 의도를 더 잘 전달할 수 있을지를 더 작은 스케일, 더 좁은 간격으로 고민할 필요가 있다. 깃헙 코파일럿 대신 Cursor를 쓰고 있다면, 심지어 편집을 마친 후 커서를 어디에 가져다 놓을지도 중요해진다.
언제 무엇을 AI에게 시킬지 판단하기
인간-AI 협업이 어떤 상황에서 더 나은 결과를 보이는지에 대한 메타 연구(When combinations of humans and AI are useful - A systematic review and meta-analysis)에 따르면
- 인간이 AI보다 잘하는 일에 AI를 붙여주면 결과가 더 좋았고
- AI가 인간보다 잘하는 일에 인간을 붙여주면 결과가 더 나빴다.
저자들은 인간이 AI보다 전반적으로 잘하는 경우에라야 AI의 제안을 수용할지 여부도 더 잘 판단할 수 있기 때문일 것으로 추측한다. 그러니까 인간이 AI보다 못하는 상황에선 AI를 의심할 타이밍에 의심 안하거나(overreliance), AI의 제안을 수용할 타이밍에 고집을 부리거나(underreliance) 한다는 얘기.
언제 어떤 일을 AI에게 시킬지, AI에게 제안한 결과를 어떤 상황에서 얼마나 신뢰할지 등을 구분하는 능력이 중요하겠다. 평소에 어떤 실천법을 쓰면 이런 능력을 개발할 수 있을지에 대해서도 고민이 필요하겠다.